import { FC, ReactElement, useEffect, useCallback, useState } from "react";
import styled from "styled-components";
import { BlogStatus, getBlogs } from "../api/blogApi";
import { Blog } from "../api/types";
import SEO from "../layout/SEO";
import BlogCard from "../components/BlogList/BlogCard";
import Pagination from "../components/BUI/Pagination";
import { ContentWidth } from "../components/commentStyled";
import Options from "../components/BlogList/Options";
import { useMount } from "../hooks";
import { getAllBlogTags, ITag } from "../api/tagApi";

interface IProps {
  tag: string;
}

const pageCount = 10; //一页10条博客

const BlogList: FC<IProps> = ({ tag }): ReactElement => {
  const [blogList, setBlogList] = useState<Blog[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [page, setPage] = useState(1);
  const [tags, setTags] = useState<ITag[]>([]);
  const [filterTag, setFilterTag] = useState<string>(tag);
  const [sort, setSort] = useState<{ field: string; value: 1 | -1 }>({
    field: "createAt",
    value: -1,
  });

  const updateSort =
    (field: "field" | "value", value: 1 | -1 | "createAt" | "updateAt") =>
    () => {
      setSort(prev => ({ ...prev, [field]: value }));
    };

  const getBlogList = useCallback(async () => {
    const find: { [key: string]: any } = { status: BlogStatus["PUBLIC"] };
    filterTag && (find.tags = { $in: [filterTag] });
    const params = {
      find,
      verify: false,
      limit: 10,
      sort: { [sort.field]: sort.value },
      skip: (page - 1) * pageCount,
    };
    console.log("params:", params);
    const { data } = await getBlogs(params);
    if (!data) return;
    const { counts, blogs } = data;
    blogs && setBlogList(blogs);
    counts && setTotalCount(counts);
  }, [page, sort, filterTag]);

  useEffect(() => {
    getBlogList();
  }, [getBlogList]);

  useMount(() => {
    getAllBlogTags().then(({ data }) => data && setTags(data));
    const query = location.search.match(/^\?tag=(\w+)(&)?/);
    if (Array.isArray(query)) setFilterTag(query[1]);
  });

  const handleChangePage = useCallback((index: number) => {
    setPage(index);
    requestAnimationFrame(() => {
      window.scrollTo(0, 0);
    });
  }, []);

  return (
    <Container>
      <SEO title="博文列表" description="宏斌的博文列表" />
      <FilterBar>
        <span data-active={sort.value === 1} onClick={updateSort("value", 1)}>
          生序
        </span>
        <span data-active={sort.value === -1} onClick={updateSort("value", -1)}>
          降序
        </span>
        <div style={{ marginLeft: "auto" }}>
          <span
            data-active={sort.field === "updateAt"}
            onClick={updateSort("field", "updateAt")}
          >
            更新时间
          </span>
          <span
            data-active={sort.field === "createAt"}
            onClick={updateSort("field", "createAt")}
          >
            发布时间
          </span>
          <Options
            data={tags}
            defaultValue={tag || "筛选博客标签"}
            onChange={tag => {
              setFilterTag(tag);
              setPage(1);
            }}
          />
        </div>
      </FilterBar>
      {blogList.map(blog => (
        <BlogCard blog={blog} key={blog._id} />
      ))}
      {totalCount > pageCount ? (
        <Pagination
          current={page}
          pageCount={pageCount}
          total={totalCount}
          onChange={handleChangePage}
        />
      ) : null}
    </Container>
  );
};

export default BlogList;

const FilterBar = styled.div`
  height: 3rem;
  color: ${props => props.theme.lightText};
  font-size: 1rem;
  letter-spacing: 2px;
  display: flex;
  align-items: flex-end;

  span {
    cursor: pointer;
    transition: all 0.3s linear;
    margin-right: 0.5rem;
  }

  span[data-active="true"] {
    font-size: 1.2rem;
    font-weight: bold;
  }

  & > div {
    display: flex;
    align-items: flex-end;
  }
`;

export const Container = styled.div`
  width: ${props => props.theme.contentWidth};
  min-height: 100vh;
  margin: 0 auto;
  ${ContentWidth};
  padding: 0 1rem;
`;

export const getServerSideProps = async ({ query }: any) => ({
  props: { tag: query.tag || "" },
});
